package DAO;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.cassandra.thrift.*;
import org.apache.thrift.TException;
import pojo.User;

public class UserDAO {
    private static Cassandra.Client client;
    private static UserDAO instance;
    
    public static UserDAO getInstance(Cassandra.Client _client)
    {
        if (instance != null)
            return instance;
        instance = new UserDAO();
        client = _client;
        return instance;
    }
    /*
    public boolean savefavoriteStatus_T(String UserID,String StatusID)
    {
        boolean result = false;
        try {
            ByteBuffer rowkey = common.GeneralHandling.toByteBuffer(UserID);
           
            ColumnPath path = new ColumnPath(User.col_parent);
            path.super_column = common.GeneralHandling.toByteBuffer(User.col_favorite);
            
            
            //Kiểm tra xem UserID đã được insert chưa bằng cách  lấy hết UserID lên so sánh.
            ColumnParent parent = new ColumnParent(User.col_parent);
            SlicePredicate predicate = new SlicePredicate();
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(User.col_favorite));
            
            KeyRange range = new KeyRange();
            range.start_key = common.GeneralHandling.toByteBuffer("");
            range.end_key = common.GeneralHandling.toByteBuffer("");
            
            List<KeySlice> list = client.get_range_slices(parent, predicate, range, common.Constants.CL);
            
            SuperColumn supercol = new SuperColumn();
            supercol.setName(common.GeneralHandling.toByteBuffer(User.col_favorite));
            
            for (KeySlice keySlice : list) {
                if (keySlice.key == common.GeneralHandling.toByteBuffer(UserID))
                {
                    supercol = (client.get(rowkey, path, common.Constants.CL)).super_column;
                    break;
                }
            }
            
            supercol.addToColumns(common.GeneralHandling.createCol(StatusID, ""));
            Addsupercolumn(rowkey, supercol);
            result = true;
            
        } catch (InvalidRequestException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NotFoundException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return result;
    }
    
    public String selectfavoriteStatus_T(String UserID)
    {
        String result = "";
        try {
            ByteBuffer rowkey = common.GeneralHandling.toByteBuffer(UserID);
               
            ColumnPath path = new ColumnPath(User.col_parent);
            path.super_column = common.GeneralHandling.toByteBuffer(User.col_favorite);

            SuperColumn supercol = (client.get(rowkey, path, common.Constants.CL)).getSuper_column();
            result = ParseToJSON(supercol);
            
        } catch (InvalidRequestException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NotFoundException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return result;
    }
    
    public boolean deletefavoriteStatus_T(String UserID, String statusID)
    {
        boolean result = false;
        try {
            ByteBuffer rowkey = common.GeneralHandling.toByteBuffer(UserID);
               
            ColumnPath path = new ColumnPath(User.col_parent);
            path.super_column = common.GeneralHandling.toByteBuffer(User.col_favorite);

            SuperColumn supercol = (client.get(rowkey, path, common.Constants.CL)).super_column;
            
            SuperColumn newsupercol = new SuperColumn();
            newsupercol.setName(supercol.name);
            for (Column col : supercol.getColumns()) {
                if (common.GeneralHandling.toString(col.name).equals(statusID))
                {
                    col.value = common.GeneralHandling.toByteBuffer(" 1");
                    newsupercol.addToColumns(col);
                }
                else
                    newsupercol.addToColumns(col);
            }
            client.remove(rowkey, path, System.currentTimeMillis(), common.Constants.CL);
            Addsupercolumn(rowkey, newsupercol);
            
            result = true;
            
        } catch (InvalidRequestException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NotFoundException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }
    
    public void Addsupercolumn(ByteBuffer rowkey, SuperColumn supercol)
    {
        try {
            List<Mutation> mutations = new ArrayList<Mutation>();

            ColumnOrSuperColumn colorsupcol = new ColumnOrSuperColumn();
            Mutation m = new Mutation();

            colorsupcol.setSuper_column(supercol);
            m.setColumn_or_supercolumn(colorsupcol);
            mutations.add(m);

            Map<String, List<Mutation>> keyMutations = new HashMap<String, List<Mutation>>();
            keyMutations.put(User.col_parent, mutations);

            Map<ByteBuffer, Map<String, List<Mutation>>> mutationsMap = new HashMap<ByteBuffer, Map<String, List<Mutation>>>();
            mutationsMap.put(rowkey, keyMutations);
            client.batch_mutate(mutationsMap, common.Constants.CL);
        
        } catch (InvalidRequestException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    */
    public boolean savefavoriteStatus(String UserID,String statusID)
    {
        boolean result = update(UserID,statusID,"0");
        return result;
    }
    
    public boolean deletefavoriteStatus(String UserID, String statusID)
    {
        boolean result = update(UserID,statusID,"1");
        return result;
    }
    
    public boolean update(String UserID, String statusID,String state)
    {
        boolean result = false;
        try {
            ByteBuffer rowkey = common.GeneralHandling.toByteBuffer(UserID);
            ColumnParent parent = new ColumnParent(User.col_parent);
            Column col = common.GeneralHandling.createCol(statusID, state);
            client.insert(rowkey, parent, col, common.Constants.CL);
            result = true;
        } catch (InvalidRequestException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }
    
    public String selectfavoriteStatus(String UserID)
    {
        String result="";
        try {
            ByteBuffer rowkey = common.GeneralHandling.toByteBuffer(UserID);
            ColumnParent parent = new ColumnParent(User.col_parent);
            SlicePredicate predicate = new SlicePredicate();
            SliceRange range = new SliceRange();
            range.start = common.GeneralHandling.toByteBuffer("");
            range.finish = common.GeneralHandling.toByteBuffer("");
            predicate.slice_range = range;
            
            List<ColumnOrSuperColumn> listcol = client.get_slice(rowkey, parent, predicate, common.Constants.CL);
            List<ByteBuffer> liststatusID = new ArrayList<ByteBuffer>();
            for (ColumnOrSuperColumn columnOrSuperColumn : listcol) {
                Column col = columnOrSuperColumn.getColumn();
                String x = common.GeneralHandling.toString(col.value);
                if (x.equals("0"))
                    liststatusID.add(col.name);
            }
            StatusDAO status_DAO = StatusDAO.getInstance(client);
            result = status_DAO.Getliststatus(liststatusID);
        
        } catch (InvalidRequestException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }
    
    public String ParseToJSON(SuperColumn supercol) throws UnsupportedEncodingException
    {
        List<ByteBuffer> liststatusID = new ArrayList<ByteBuffer>();
        for (Column col : supercol.getColumns()) {
            if (!"1".equals(common.GeneralHandling.toString(col.value)))
                liststatusID.add(col.name);
        }
        StatusDAO status_DAO = StatusDAO.getInstance(client);
        String result = status_DAO.Getliststatus(liststatusID);
        return result;
    }
}
